<!--
 * Copyright (c) 2022 - present TinyVue Authors.
 * Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
 *
 * Use of this source code is governed by an MIT-style license.
 *
 * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
 * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
 * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
 *
 -->
<template>
  <transition name="tiny-zoom-in-top" @after-enter="handleEnter" @after-leave="handleLeave">
    <div
      class="tiny-picker-panel tiny-date-picker tiny-popper"
      :class="[
        {
          'has-sidebar': slots.sidebar || state.shortcuts?.length,
          'has-time': state.showTime
        },
        state.popperClass
      ]"
    >
      <div class="tiny-picker-panel__body-wrapper">
        <slot name="sidebar" class="tiny-picker-panel__sidebar"></slot>

        <!-- 快捷选项 -->
        <div class="tiny-picker-panel__sidebar" v-if="state.shortcuts?.length">
          <button
            type="button"
            class="tiny-picker-panel__shortcut"
            v-for="(shortcut, key) in state.shortcuts"
            :key="key"
            @click="handleShortcutClick(shortcut)"
            :title="shortcut.text"
          >
            {{ shortcut.text }}
          </button>
        </div>

        <div class="tiny-picker-panel__body">
          <!-- 时间选择输入框 -->
          <div class="tiny-date-picker__time-header" v-if="state.showTime">
            <span class="tiny-date-picker__editor-wrap">
              <tiny-input
                :placeholder="t('ui.datepicker.selectDate')"
                :model-value="state.visibleDate"
                size="small"
                @update:modelValue="(val) => (state.userInputDate = val)"
                @change="handleVisibleDateChange"
              />
            </span>
            <span class="tiny-date-picker__editor-wrap" v-clickoutside="handleTimePickClose">
              <tiny-input
                ref="input"
                @focus="state.timePickerVisible = true"
                :placeholder="t('ui.datepicker.selectTime')"
                :model-value="state.visibleTime"
                size="small"
                @update:modelValue="(val) => (state.userInputTime = val)"
                @change="handleVisibleTimeChange"
                :readonly="!timeEditable"
              />
              <time-picker
                ref="timepicker"
                :step="step"
                :time-arrow-control="state.arrowControl"
                :show="state.timePickerVisible"
                :value="state.date"
                @pick="handleTimePick"
              >
              </time-picker>
            </span>
          </div>

          <!-- 上一年/上一月/下一月/下一年 -->
          <div
            class="tiny-date-picker__header"
            :class="{
              'tiny-date-picker__header--bordered': ['month', 'year', 'years', 'yearrange'].includes(state.currentView)
            }"
            v-show="state.currentView !== 'time'"
          >
            <button
              type="button"
              @click="cusPrevYear"
              :aria-label="t(`ui.datepicker.prevYear`)"
              class="tiny-picker-panel__icon-btn tiny-date-picker__prev-btn tiny-icon-d-arrow-left"
            >
              <icon-double-left></icon-double-left>
            </button>
            <button
              type="button"
              @click="cusPrevMonth"
              v-show="state.currentView === 'date'"
              :aria-label="t(`ui.datepicker.prevMonth`)"
              class="tiny-picker-panel__icon-btn tiny-date-picker__prev-btn tiny-icon-arrow-left"
            >
              <icon-chevron-left></icon-chevron-left>
            </button>
            <span @click="showHeaderPicker('Year')" role="button" class="tiny-date-picker__header-label">
              {{ state.yearLabel }}
            </span>
            <span
              @click="showHeaderPicker('Month')"
              v-show="state.currentView === 'date'"
              role="button"
              class="tiny-date-picker__header-label"
              :class="{ active: state.currentView === 'month' }"
              >{{ t(`ui.datepicker.month${state.month + 1}`) }}</span
            >
            <button
              type="button"
              @click="cusNextYear"
              :aria-label="t(`ui.datepicker.nextYear`)"
              class="tiny-picker-panel__icon-btn tiny-date-picker__next-btn tiny-icon-d-arrow-right"
            >
              <icon-double-right></icon-double-right>
            </button>
            <button
              type="button"
              @click="cusNextMonth"
              v-show="state.currentView === 'date'"
              :aria-label="t(`ui.datepicker.nextMonth`)"
              class="tiny-picker-panel__icon-btn tiny-date-picker__next-btn tiny-icon-arrow-right"
            >
              <icon-chevron-right></icon-chevron-right>
            </button>
          </div>

          <!-- 日期表格 -->
          <div class="tiny-picker-panel__content">
            <div class="tiny-picker-panel__table">
              <date-table
                ref="dateTable"
                v-if="state.currentView === 'date'"
                @pick="handleDatePick"
                :selection-mode="state.selectionMode"
                :first-day-of-week="state.firstDayOfWeek"
                :value="state.value"
                :default-value="state.defaultValue ? new Date(state.defaultValue) : null"
                :date="state.date"
                :cell-class-name="state.cellClassName"
                :disabled-date="state.disabledDate"
                :show-week-number="showWeekNumber"
                :format-weeks="formatWeeks"
                :readonly="readonly"
              >
              </date-table>
              <year-table
                ref="yearTable"
                v-if="['year', 'years', 'yearrange'].includes(state.currentView)"
                :value="state.value"
                :default-value="state.defaultValue ? new Date(state.defaultValue) : null"
                :date="state.date"
                :disabled-date="state.disabledDate"
                :selection-mode="state.selectionMode"
                :start-year="state.startYear"
                :readonly="readonly"
                @pick="handleYearPick"
              >
              </year-table>
              <month-table
                ref="monthTable"
                v-if="state.currentView === 'month'"
                @pick="handleMonthPick"
                :value="state.value"
                :default-value="state.defaultValue ? new Date(state.defaultValue) : null"
                :date="state.date"
                :disabled-date="state.disabledDate"
              >
              </month-table>
            </div>
          </div>
        </div>
      </div>

      <!-- 时区选择 -->
      <div
        class="tiny-picker-panel__timezone"
        v-if="state.isShowTz || state.timezone.isServiceTimezone"
        v-clickoutside="handleTzPickClose"
      >
        <tiny-input
          v-model="state.tz"
          :disabled="state.timezone.isServiceTimezone"
          @update:modelValue="searchTz"
          :placeholder="t('ui.datepicker.timezone')"
        >
          <template #suffix>
            <component fill="#ccc" :is="state.showpopup ? 'IconChevronDown' : 'IconChevronUp'" @click="toggleTz" />
          </template>
        </tiny-input>
        <div class="tiny-picker-panel__tzlist">
          <tiny-popup v-model="state.showpopup" :overlay="false" position="up" :duration="0.2" :closeable="false">
            <div class="tzlist">
              <ul>
                <li
                  class="tiny-picker-panel__tzlist-li"
                  :title="tz.name"
                  v-show="!tz.visible"
                  v-for="(tz, index) in state.renderTzdata"
                  :key="index"
                  @click="selectTz(tz)"
                >
                  {{ tz.name }}
                </li>
              </ul>
            </div>
          </tiny-popup>
        </div>
      </div>

      <!-- 此刻/确认 -->
      <div
        class="tiny-picker-panel__footer"
        v-if="state.isShowFooter || $slots.footer || $slots.now || $slots.confirm"
        :style="{ justifyContent: !['dates', 'years'].includes(state.selectionMode) ? 'space-between' : 'right' }"
      >
        <slot name="footer" :confirm="confirm">
          <slot name="now" :change-to-now="changeToNow">
            <tiny-button
              :size="state.buttonSize"
              type="text"
              class="tiny-picker-panel__link-btn"
              @click="changeToNow"
              v-show="!['dates', 'years'].includes(state.selectionMode)"
            >
              {{ t('ui.datepicker.now') }}
            </tiny-button>
          </slot>
          <slot name="confirm">
            <tiny-button
              :type="state.buttonType"
              :size="state.buttonSize"
              class="tiny-picker-panel__link-btn"
              @click="confirm"
            >
              {{ t('ui.datepicker.confirm') }}
            </tiny-button>
          </slot>
        </slot>
      </div>
    </div>
  </transition>
</template>

<script lang="ts">
import { renderless, api } from '@opentiny/vue-renderless/date-panel/vue'
import { $prefix, setup, directive, defineComponent, $props } from '@opentiny/vue-common'
import { language } from '@opentiny/vue-locale'
import { Clickoutside } from '@opentiny/vue-directive'
import TimePicker from '@opentiny/vue-time'
import DateTable from '@opentiny/vue-date-table'
import YearTable from '@opentiny/vue-year-table'
import MonthTable from '@opentiny/vue-month-table'
import Input from '@opentiny/vue-input'
import Button from '@opentiny/vue-button'
import {
  iconDoubleRight,
  iconDoubleLeft,
  iconChevronLeft,
  iconChevronRight,
  iconChevronDown,
  iconChevronUp
} from '@opentiny/vue-icon'
import Popup from '@opentiny/vue-popup'

export default defineComponent({
  name: $prefix + 'DatePanel',
  directives: directive({ Clickoutside }),
  components: {
    TimePicker,
    YearTable,
    MonthTable,
    DateTable,
    TinyInput: Input,
    TinyButton: Button,
    TinyPopup: Popup,
    IconDoubleRight: iconDoubleRight(),
    IconDoubleLeft: iconDoubleLeft(),
    IconChevronLeft: iconChevronLeft(),
    IconChevronRight: iconChevronRight(),
    IconChevronDown: iconChevronDown(),
    IconChevronUp: iconChevronUp()
  },
  props: {
    ...$props,
    emitter: Object,
    step: {
      type: Object,
      default() {
        return { hour: 1, minute: 1, second: 1 }
      }
    },
    showWeekNumber: {
      type: Boolean,
      default: false
    },
    formatWeeks: Function,
    type: {
      type: String,
      default: ''
    },
    firstDayOfWeek: {
      type: Number,
      default: 7
    },
    timeEditable: {
      type: Boolean,
      default: true
    },
    nowClick: {
      type: Function
    },
    modelValue: {
      type: [Date, String, Number],
      default: ''
    },
    format: {
      type: String,
      default: ''
    },
    readonly: {
      type: Boolean,
      default: false
    },
    shortcuts: {
      type: Array,
      default: () => []
    },
    disabledDate: {
      type: Function,
      default: () => null
    },
    popperClass: {
      type: String,
      default: ''
    }
  },
  emits: ['pick', 'select-change', 'update:modelValue', 'dodestroy'],
  setup(props, context) {
    return setup({
      props,
      context,
      renderless,
      api,
      extendOptions: { language }
    })
  }
})
</script>
